﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Nina.Codec
{
    /// <summary>
    /// A codec for prefixing packets with their length
    /// </summary>
    public class PacketLengthCodec : NinaCodec
    {

        public override void OnSessionStarted(NinaSession session)
        {
            /* Do nothing */
        }

        public override void OnSessionClosed(NinaSession session)
        {
            /* Do nothing */
        }

        public override bool OnRead(NinaSession session, ref byte[] data, ref byte[] remaining)
        {
            if (data.Length < 4)
            {
                /* Incomplete packet */
                remaining = data;
                data = new byte[0];
                return false;
            }

            int totalBytes = BitConverter.ToInt32(data, 0);
            int dataBytes = data.Length - 4;
            if (dataBytes == totalBytes)
            {
                /* Complete packet */
                byte[] result = new byte[totalBytes];
                for (int i = 4; i < data.Length; i++)
                {
                    result[i - 4] = data[i];
                }
                data = result;
                remaining = new byte[0];
                return true;
            }
            else if (dataBytes > totalBytes)
            {
                /* Complete packet with extra bytes */
                byte[] result = new byte[totalBytes];
                for (int i = 0; i < result.Length; i++)
                {
                    result[i] = data[i + 4];
                }

                List<byte> remainingBytes = new List<byte>();
                for (int i = totalBytes + 4; i < data.Length; i++)
                {
                    remainingBytes.Add(data[i]);
                }

                data = result;
                remaining = remainingBytes.ToArray<byte>();
                return true;
            }
            else
            {
                /* Incomplete packet */
                remaining = data;
                data = new byte[0];
                return false;
            }
        }

        public override byte[] OnWrite(NinaSession session, byte[] data)
        {
            byte[] lengthBytes = BitConverter.GetBytes(data.Length);
            List<byte> result = new List<byte>();
            result.AddRange(lengthBytes);
            result.AddRange(data);
            return result.ToArray<byte>();
        }
    }
}
